﻿
// ———————————————————————–
// <copyright file="ResourceStatusGenerator.cs" company="The MITRE Corporation">
//    Copyright (c) 2014 The MITRE Corporation. All rights reserved.
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//    http://www.apache.org/licenses/LICENSE-2.0
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
// </copyright>
// ———————————————————————–
/////////////////////////////////////////////////////////////////////////////////////////////////
// ResourceStatusGenerator.cs:
//
// A generator for good and bad examples of ResourceStatus.
//
// Project: NIEMCADTest
// Author:  Lizzie DeYoung - MITRE
/////////////////////////////////////////////////////////////////////////////////////////////////

// Copyright (c) 2014 The MITRE Corporation. All rights reserved.
//
// NOTICE
// This software was produced for the U. S. Government
// under Contract No. FA8721-09-C-0001, and is
// subject to the Rights in Noncommercial Computer Software
// and Noncommercial Computer Software Documentation Clause
// (DFARS) 252.227-7014 (JUN 1995)  
      

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using EDXLSharp.NIEMCADLib;
using EDXLSharp.NIEMMilOpsLib;
using EDXLSharp;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Diagnostics;

namespace NIEMCADTest.ResourceDetailTests
{
  class ResourceStatusGenerator : Generator
  {
    public const string PRIMARY_STATUS = "primaryStatus";
    public const string SECONDARY_STATUS = "secondaryStatus";
    public const string SECONDARY_STATUS_TYPE = "secondaryStatusType";

    public const string RESOURCE_UCAD_STATUS = "ResourceUCADStatus";
    public const string RESOURCE_EIDD_STATUS = "ResourceEIDDStatus";
    public const string RESOURCE_SECONDARY_STATUS = "ResourceSecondaryStatusText";

    //TODO: LDY modify these to use $namespace$ $name$ and $prefix$
    //TODO: TEST modify all references to these xml strings with GetXml from superclass.
    public const string RESOURCE_STATUS_EMPTY = @"
		<cad:ResourceStatus xmlns:cad='http://mitre.org/emevent/0.8/cad2cad/'>
		</cad:ResourceStatus>";

    public const string RESOURCE_STATUS_PRIMARY_ONLY = @"
		<cad:ResourceStatus xmlns:cad='http://mitre.org/emevent/0.8/cad2cad/'>
			<cad:ResourcePrimaryStatus>$code</cad:ResourcePrimaryStatus>
		</cad:ResourceStatus>";

    public const string RESOURCE_STATUS_SECONDARY_ONLY = @"
		<cad:ResourceStatus xmlns:cad='http://mitre.org/emevent/0.8/cad2cad/'>
			<cad:$elementname>$code</cad:$elementname>
		</cad:ResourceStatus>";

    public const string RESOURCE_STATUS = @"
		<cad:ResourceStatus xmlns:cad='http://mitre.org/emevent/0.8/cad2cad/'>
			<cad:ResourcePrimaryStatus>$primarycode</cad:ResourcePrimaryStatus>
			<cad:$elementname>$secondarycode</cad:$elementname>
		</cad:ResourceStatus>";

    public static string[] SECONDARY_RESOURCE_TYPES =
      new string[3] { RESOURCE_UCAD_STATUS, RESOURCE_EIDD_STATUS, RESOURCE_SECONDARY_STATUS };

    public ResourceStatusGenerator()
    {
      elementName = "ResourceStatus";
      elementNamespace = "http://mitre.org/emevent/0.8/cad2cad/";
      elementPrefix = "cad";
    }

    public List<TestObject> BAD_ResourceStatusEmpty()
    {
      string xml = RESOURCE_STATUS_EMPTY;
      TestObject testObject = GetTestObject(xml, null, null, null);
      List<TestObject> list = new List<TestObject>();
      
      list.Add(testObject);

      return list;
    }

    public List<TestObject> BAD_ResourceNoPrimaryStatus()
    {
      List<TestObject> list = new List<TestObject>();
      TestObject testObject;

      foreach (string secondaryResourceType in SECONDARY_RESOURCE_TYPES)
      {
        string baseXml = RESOURCE_STATUS_SECONDARY_ONLY.Replace("$elementname", secondaryResourceType);
        string xml, text;
        switch (secondaryResourceType)
        {
          case RESOURCE_UCAD_STATUS:
            foreach (ResourceUCADStatusCode code in Enum.GetValues(typeof(ResourceUCADStatusCode)))
            {
              text = code.GetText();
              xml = baseXml.Replace("$code", text);
              testObject = GetTestObject(xml, null, secondaryResourceType, text);
              list.Add(testObject);
            }
            break;
          case RESOURCE_EIDD_STATUS:
            foreach (ResourceEIDDStatusCode code in Enum.GetValues(typeof(ResourceEIDDStatusCode)))
            {
              text = code.GetText();
              xml = baseXml.Replace("$code", text);
              testObject = GetTestObject(xml, null, secondaryResourceType, text);
              list.Add(testObject);
            }
            break;
          case RESOURCE_SECONDARY_STATUS:
            text = "this is a status";
            xml = baseXml.Replace("$code", text);
            testObject = GetTestObject(xml, null, secondaryResourceType, text);
            list.Add(testObject);
            break;
          default:
            throw new Exception("something bad happened");
        }
      }

      return list;
    }

    public List<TestObject> GOOD_ResourceOnlyPrimaryStatus()
    {
      List<TestObject> list = new List<TestObject>();
      TestObject testObject;

      foreach (ResourcePrimaryStatusCode code in Enum.GetValues(typeof(ResourcePrimaryStatusCode)))
      {
        string text = code.GetText();
        string xml = RESOURCE_STATUS_PRIMARY_ONLY.Replace("$code", text);

        testObject = GetTestObject(xml, text, null, null);
        list.Add(testObject);
      }

      return list;
    }

    public List<TestObject> GOOD_ResourcePrimaryAndSecondaryStatus()
    {
      List<TestObject> list = new List<TestObject>();
      TestObject testObject;

      foreach (ResourcePrimaryStatusCode primaryCode in Enum.GetValues(typeof(ResourcePrimaryStatusCode)))
      {
        string primaryCodeText = primaryCode.GetText();
        string primaryStatusXml = RESOURCE_STATUS.Replace("$primarycode", primaryCodeText);

        foreach (string secondaryResourceType in SECONDARY_RESOURCE_TYPES)
        {
          string secondaryStatusXml = primaryStatusXml.Replace("$elementname", secondaryResourceType);
          string xml, secondaryCodetext;
          switch (secondaryResourceType)
          {
            case RESOURCE_UCAD_STATUS:
              foreach (ResourceUCADStatusCode secondaryCode in Enum.GetValues(typeof(ResourceUCADStatusCode)))
              {
                secondaryCodetext = secondaryCode.GetText();
                xml = secondaryStatusXml.Replace("$secondarycode", secondaryCodetext);
                testObject = GetTestObject(xml, primaryCodeText, secondaryResourceType, secondaryCodetext);
                list.Add(testObject);
              }
              break;
            case RESOURCE_EIDD_STATUS:
              foreach (ResourceEIDDStatusCode secondaryCode in Enum.GetValues(typeof(ResourceEIDDStatusCode)))
              {
                secondaryCodetext = secondaryCode.GetText();
                xml = secondaryStatusXml.Replace("$secondarycode", secondaryCodetext);
                testObject = GetTestObject(xml, primaryCodeText, secondaryResourceType, secondaryCodetext);
                list.Add(testObject);
              }
              break;
            case RESOURCE_SECONDARY_STATUS:
              secondaryCodetext = "this is a status";
              xml = secondaryStatusXml.Replace("$secondarycode", secondaryCodetext);
              testObject = GetTestObject(xml, primaryCodeText, secondaryResourceType, secondaryCodetext);
              list.Add(testObject);
              break;
            default:
              throw new Exception("something went wrong with the test...");
          }
        }
      }

      return list;
    }

    //TODO: LDY implement this once the resource secondary status turns into a list
    /*
    public static List<XmlNode> GOOD_ResourcePrimaryAndMultipleSecondaryStatus() { throw new NotImplementedException(); }
    */

    private TestObject GetTestObject(string xml, string primaryStatus, string secondaryStatusType, string secondaryStatus)
    {
      TestObject testObject = this.GetTestObject(xml);

      if (!string.IsNullOrWhiteSpace(primaryStatus))
      {
        testObject.TestParameters.Add(PRIMARY_STATUS, primaryStatus);
      }
      if (!string.IsNullOrWhiteSpace(secondaryStatusType))
      {
        testObject.TestParameters.Add(SECONDARY_STATUS_TYPE, secondaryStatusType);
      }
      if (!string.IsNullOrWhiteSpace(secondaryStatus))
      {
        testObject.TestParameters.Add(SECONDARY_STATUS, secondaryStatus);
      }

      return testObject;
    }
  }
}
